﻿<%@ Page Language="C#" MasterPageFile="~/_layouts/application.master" AutoEventWireup="true"
    EnableViewState="true" %>

<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="Microsoft.SharePoint.WebControls" %>
<%@ Import Namespace="Microsoft.SharePoint.Workflow" %>
<%@ Import Namespace="System.Web.UI" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Web" %>
<%@ Import Namespace="System.Web.UI" %>
<%@ Import Namespace="System.Web.UI.WebControls" %>
<%@ Import Namespace="System.Xml" %>
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"
    Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
    <table class="ms-formtable" border="0" cellpadding="0" cellspacing="0" width="100%">
        <tr>
            <td colspan="2" valign="top" class="ms-formlabel">
                <asp:Label ID="lblError" runat="server" />
            </td>
        </tr>
        <tr>
            <td valign="top" style="width: 50%" class="ms-formlabel">
                <asp:TreeView ID="treSites" runat="server" NodeStyle-CssClass="ms-formlabel" NodeStyle-Width="100%" />
            </td>
            <td valign="top" class="ms-formlabel" style="width: 50%">
                 <table class="ms-formtable" border="0" cellpadding="0" cellspacing="0" width="100%">
                    <tr>
                        <td valign="top" class="ms-formbody">
                            <asp:CheckBox ID="chkDeactivateApprovalOnDocumentsList" runat="server" Text="Disable Approval Worflow on Images and Documents Library" AutoPostBack="true"
                                OnCheckedChanged="chkDeactivateApprovalOnDocumentsList_CheckedChanged" />
                        </td>
                    </tr>
                </table>
                <table class="ms-formtable" border="0" cellpadding="0" cellspacing="0" width="100%">
                    <tr>
                        <td valign="top" class="ms-formbody">
                            <asp:CheckBox ID="chkApproval" runat="server" Text="Enable Approval on Pages Library" AutoPostBack="true"
                                OnCheckedChanged="chkApproval_CheckedChanged" />
                        </td>
                    </tr>
                </table>
                <asp:Panel ID="pnlApprovalSettings" runat="server" Visible="true">
                    <table class="ms-formtable" border="0" cellpadding="0" cellspacing="0" width="100%">
                        <tr>
                            <td valign="top" class="ms-formbody" style="width: 100%">
                                <asp:CheckBox ID="chkWorkflowParalel" runat="server" Checked="true" Text="Start Workflow parallel" AutoPostBack="true"
                                    OnCheckedChanged="chkWorkflowParalel_CheckedChanged" />
                            </td>
                        </tr>
                        <tr>
                            <td valign="top" class="ms-formbody" style="width: 100%">
                                <asp:CheckBox ID="chkSetDefaultApprovers" runat="server" AutoPostBack="true" Text="Set default approver"
                                    OnCheckedChanged="chkSetDefaultApprovers_CheckedChanged" />
                                <asp:Panel ID="pnlDefaultApprover" runat="server">
                                    <table border="0" cellpadding="0" cellspacing="0" width="100%">
                                        <tr>
                                            <td valign="top" class="ms-formlabel" style="width: 100%">
                                                <asp:RadioButton GroupName="UserSelect" ID="radNo" runat="server" Text="No default approver" />
                                            </td>
                                        </tr>
                                        <tr>
                                            <td valign="top" class="ms-formlabel">
                                                <asp:RadioButton GroupName="UserSelect" ID="radSharePointGroup" runat="server" Text="SharePoint Group" />
                                                <br />
                                                <asp:DropDownList ID="drpGroup" runat="server" />
                                            </td>
                                        </tr>
                                        <tr>
                                            <td valign="top" class="ms-formlabel">
                                                <asp:RadioButton GroupName="UserSelect" ID="radWindowsUser" runat="server" Text="Active Directory User (Login)" /><br />
                                                <asp:TextBox ID="txtWindowsLogin" runat="server" />
                                            </td>
                                        </tr>
                                        <tr>
                                            <td valign="top" class="ms-formlabel">
                                                <asp:RadioButton GroupName="UserSelect" ID="radWindowsGroup" runat="server" Text="Active Directory Group" /><br />
                                                <asp:TextBox ID="txtWindowsGroup" runat="server" />
                                            </td>
                                        </tr>
                                    </table>
                                </asp:Panel>
                            </td>
                        </tr>
                        <tr>
                            <td valign="top" class="ms-formbody">
                                <asp:CheckBox ID="chkAllowChanges" runat="server" Text="Allow changes to the participant list by user" />
                            </td>
                        </tr>
                        <tr>
                            <td valign="top" class="ms-formbody">
                                <asp:CheckBox ID="chkSingleTask2Group" runat="server" Text="Assign a single task to a group (don't expand)" />
                            </td>
                        </tr>
                        <tr>
                            <td valign="top" class="ms-formbody">
                                <asp:CheckBox ID="chkCompleteWF" runat="server" Text="Complete this workflow when"
                                    OnCheckedChanged="chkCompleteWF_CheckedChanged" AutoPostBack="true" />
                                <asp:Panel ID="pnlCompleteWF" runat="server">
                                    Following number of tasks are finished:
                                    <asp:TextBox ID="txtWantedTasks" runat="server" />
                                </asp:Panel>
                            </td>
                        </tr>
                    </table>
                </asp:Panel>
            </td>
        </tr>
        <tr>
            <td>
                <asp:Button ID="btnApply" runat="server" Text="Apply Approval Workflow Settings"
                    OnClick="btnApply_Click" />
            </td>
            <td>
            </td>
        </tr>
        <tr>
            <td>
                &nbsp;
            </td>
        </tr>
        <tr>
            <td colspan="2" class="ms-formlabel">
                Created by <a href="http://blog.sharepoint.ch">David Schneider</a>.
            </td>
        </tr>
    </table>
</asp:Content>
<asp:Content ID="BreadCrumb" ContentPlaceHolderID="PlaceHolderTitleBreadcrumb" runat="server">
    <asp:HyperLink ID="hlBack" runat="server" />
</asp:Content>
<asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea"
    runat="server">
    <asp:Label ID="lbPageTitle" runat="server" Text="Publishing Approval Workflow Settings" />
</asp:Content>
<asp:Content ID="TopMenu" ContentPlaceHolderID="PlaceHolderPageDescription" runat="server">
    <asp:Label ID="lbPageDescription" runat="server" Text="Modify the approval workflow settings on every 'Pages' library." />
</asp:Content>

<script runat="server">
    const string CT_SYSTEM_PAGE = "0x010100C568DB52D9D0A14D9B2FDCC96666E9F2";
    const string SCHEMA = "http://schemas.microsoft.com/office/infopath/2003/myXSD";

    protected override void OnLoad(EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            TreeNode rootNode = new TreeNode("Root");
            treSites.Nodes.Add(rootNode);
            AddNodes(rootNode, SPContext.Current.Site.RootWeb);

            drpGroup.Items.Clear();
            foreach (SPGroup group in SPContext.Current.Site.RootWeb.SiteGroups)
            {
                drpGroup.Items.Add(group.Name);
            }

            pnlApprovalSettings.Visible = false;
            pnlDefaultApprover.Visible = false;
            pnlCompleteWF.Visible = false;
        }
    }

    #region HelperMethods
    private void AddNodes(TreeNode pParentNode, SPWeb pParentSite)
    {
        foreach (SPWeb site in pParentSite.Webs)
        {
            TreeNode node = new TreeNode();
            node.Text = string.Format("{0} ({1})", site.Title, site.Url);
            node.Value = site.ID.ToString();
            node.ShowCheckBox = true;
            pParentNode.ChildNodes.Add(node);
            AddNodes(node, site);
            site.Dispose();
        }
    }
    //private void SetCheckbox(TreeNode parentNode, bool chechboxChecked)
    //{
    //    parentNode.Checked = chechboxChecked;
    //    foreach (TreeNode node in parentNode.ChildNodes)
    //    {
    //        SetCheckbox(node, chechboxChecked);
    //    }
    //}
    #endregion

    #region Events
    //private void treSites_NodeCheckChanged(object sender, TreeNodeEventArgs e)
    //{
    //    foreach (TreeNode node in e.Node.ChildNodes)
    //    {
    //        SetCheckbox(node, e.Node.Checked);
    //    }
    //}

    private void chkCompleteWF_CheckedChanged(object sender, EventArgs e)
    {
        pnlCompleteWF.Visible = chkCompleteWF.Checked;
    }
    private void chkApproval_CheckedChanged(object sender, EventArgs e)
    {
        pnlApprovalSettings.Visible = chkApproval.Checked;
    }
    private void chkDeactivateApprovalOnDocumentsList_CheckedChanged(object sender, EventArgs e)
    {
    }
    private void chkWorkflowParalel_CheckedChanged(object sender, EventArgs e)
    {
    }
    private void chkSetDefaultApprovers_CheckedChanged(object sender, EventArgs e)
    {
        pnlDefaultApprover.Visible = chkSetDefaultApprovers.Checked;
    }

    private void btnApply_Click(object sender, EventArgs e)
    {
        if (chkSetDefaultApprovers.Checked
                       && !radNo.Checked
                       && !radSharePointGroup.Checked
                       && !radWindowsGroup.Checked
                       && !radWindowsUser.Checked)
        {
            lblError.Text = "Please select account type.";
            lblError.Style.Add(HtmlTextWriterStyle.Color, "Red");
            return;
        }

        if (chkSetDefaultApprovers.Checked && radSharePointGroup.Checked && drpGroup.SelectedItem == null)
        {
            lblError.Text = "Please select SharePoint Group."; lblError.Style.Add(HtmlTextWriterStyle.Color, "Red");
            lblError.Style.Add(HtmlTextWriterStyle.Color, "Red");
            return;
        }

        if (chkSetDefaultApprovers.Checked && radWindowsGroup.Checked && string.IsNullOrEmpty(txtWindowsGroup.Text))
        {
            lblError.Text = "Please enter Windows Group.";
            lblError.Style.Add(HtmlTextWriterStyle.Color, "Red");
            return;
        }

        if (chkSetDefaultApprovers.Checked && radWindowsUser.Checked && string.IsNullOrEmpty(txtWindowsLogin.Text))
        {
            lblError.Text = "Please enter Windows Login.";
            lblError.Style.Add(HtmlTextWriterStyle.Color, "Red");
            return;
        }

        int cnt = 0;
        foreach (TreeNode node in treSites.Nodes)
        {
            cnt += ApplyApprovalSettings(node);
        }

        lblError.Text = string.Format("{0} sites updated!", cnt);
        lblError.Style.Add(HtmlTextWriterStyle.Color, "Green");
    }

    private int ApplyApprovalSettings(TreeNode node)
    {
        int cnt = 0;
        if (node.Checked)
        {
            using (SPWeb site = SPContext.Current.Site.OpenWeb(new Guid(node.Value)))
            {
                for (int i = 0; i < site.Lists.Count; i++)
                {
                    // foreach doesn't work, cause we're changing the lists collection
                    SPList list = site.Lists[i];

                   
                    bool isPublishingList = false;
                    bool isDocumentsList = false;
                    if (list.ContentTypesEnabled)
                    {
                        //Set isPublishingList flag
                        foreach (SPContentType ct in list.ContentTypes)
                        {
                            // System Page
                            if (ct.Id.ToString().StartsWith(CT_SYSTEM_PAGE))
                            {
                                isPublishingList = true;
                                break;
                            }
                        }
                    }
                    else
                    {
                        //Set isImagesList and isDocumentsList flag                        
                        isDocumentsList = (list.BaseTemplate == SPListTemplateType.DocumentLibrary);
                       
                    }                  
                    
                    if (isDocumentsList)
                    {
                        if (chkDeactivateApprovalOnDocumentsList.Checked)
                        {
                            list.EnableModeration = false;
                            list.EnableMinorVersions = false;
                            list.Update();
                        }
                    }
                    else if (isPublishingList)
                    {
                        cnt++;
                        if (!chkApproval.Checked)
                        {
                            list.EnableModeration = false;
                            list.Update();
                        }
                        else
                        {
                            list.EnableModeration = true;
                            list.Update();

                            SPWorkflowAssociation association = list.WorkflowAssociations[list.DefaultContentApprovalWorkflowId];
                            if (association == null)
                            {
                                String WorkflowAssociationName = "Parallel Approval";
                                String aprovalWorkflowID = "c6964bff-bf8d-41ac-ad5e-b61ec111731c";
                                String m_historyListName = "Workflow History";
                                String m_taskListName = "Workflow Tasks";
                                
                                SPWorkflowTemplate WorkflowTemplate = site.WorkflowTemplates[new Guid(aprovalWorkflowID)];
                                SPList taskList;
                                SPList historyList;
                                Guid m_taskListId = Guid.Empty;
                                Guid m_historyListId = Guid.Empty;
                               
                                try 
                                {	        
	                                  m_taskListId = site.Lists[m_taskListName].ID;
                                }
                                catch (Exception)
                                {
                                }
                                
                                try 
                                {
                                    m_historyListId = site.Lists[m_historyListName].ID;
                                }
                                catch (Exception)
                                {
                                }

                                if (m_taskListId == Guid.Empty)
                                {
                                    string description = string.Format("Task list for the {0} workflow.", WorkflowAssociationName);
                                    m_taskListId = site.Lists.Add(m_taskListName, description, SPListTemplateType.Tasks);
                                }

                                
                                if (m_historyListId == Guid.Empty)
                                {
                                    string description = string.Format("History list for the {0} workflow.", WorkflowAssociationName);
                                    m_historyListId = site.Lists.Add(m_historyListName, description, SPListTemplateType.WorkflowHistory);
                                }
                                
                                taskList = site.Lists[m_taskListId];
                                historyList = site.Lists[m_historyListId];


                                SPWorkflowAssociation newAssociation = SPWorkflowAssociation.CreateListAssociation(WorkflowTemplate, WorkflowAssociationName, taskList, historyList);

                                list.AddWorkflowAssociation(newAssociation);
                                list.DefaultContentApprovalWorkflowId=newAssociation.Id;
                                list.Update();
                                association = list.WorkflowAssociations[list.DefaultContentApprovalWorkflowId];
                            }
                            
                            if (association != null)
                            {
                                XmlDocument xmlDoc = new XmlDocument();
                                xmlDoc.LoadXml(association.AssociationData);
                                XmlNamespaceManager manager = new XmlNamespaceManager(xmlDoc.NameTable);
                                manager.AddNamespace("my", SCHEMA);
                                XmlNode xmlNode;

                                xmlNode = xmlDoc.SelectSingleNode("/my:myFields/my:Reviewers", manager);

                                if (chkSetDefaultApprovers.Checked)
                                {
                                    if (radNo.Checked)
                                    {
                                        xmlNode.RemoveAll();
                                    }
                                    else if (radWindowsUser.Checked || radSharePointGroup.Checked || radWindowsGroup.Checked)
                                    {
                                        xmlNode.RemoveAll();

                                        XmlNode personNode = xmlDoc.CreateNode(XmlNodeType.Element, "my:Person", SCHEMA);
                                        xmlNode.AppendChild(personNode);

                                        XmlNode displayNameNode = xmlDoc.CreateNode(XmlNodeType.Element, "my:DisplayName", SCHEMA);
                                        personNode.AppendChild(displayNameNode);

                                        XmlNode accountIdNode = xmlDoc.CreateNode(XmlNodeType.Element, "my:AccountId", SCHEMA);
                                        personNode.AppendChild(accountIdNode);

                                        XmlNode accountTypeNode = xmlDoc.CreateNode(XmlNodeType.Element, "my:AccountType", SCHEMA);
                                        personNode.AppendChild(accountTypeNode);

                                        if (radSharePointGroup.Checked)
                                        {
                                            //<my:DisplayName>Approvers</my:DisplayName>
                                            //<my:AccountId>Approvers</my:AccountId>
                                            //<my:AccountType>SharePointGroup</my:AccountType>
                                            displayNameNode.InnerText = drpGroup.SelectedItem.ToString();
                                            accountIdNode.InnerText = drpGroup.SelectedItem.ToString();
                                            accountTypeNode.InnerText = "SharePointGroup";
                                        }
                                        else if (radWindowsUser.Checked)
                                        {
                                            //<my:DisplayName>DOMAIN\\Administrator</my:DisplayName>
                                            //<my:AccountId>DOMAIN\\administrator</my:AccountId>
                                            //<my:AccountType>User</my:AccountType>
                                            displayNameNode.InnerText = txtWindowsLogin.Text;
                                            accountIdNode.InnerText = txtWindowsLogin.Text;
                                            accountTypeNode.InnerText = "User";
                                        }
                                        else if (radWindowsGroup.Checked)
                                        {
                                            //<my:DisplayName>DOMAIN\\group_name</my:DisplayName>
                                            //<my:AccountId>DOMAIN\\group_name</my:AccountId>
                                            //<my:AccountType>SecurityGroup</my:AccountType>
                                            displayNameNode.InnerText = txtWindowsGroup.Text;
                                            accountIdNode.InnerText = txtWindowsGroup.Text;
                                            accountTypeNode.InnerText = "SecurityGroup";
                                        }
                                    }

                                }

                                xmlNode = xmlDoc.SelectSingleNode("/my:myFields/my:InitLock", manager);
                                if (chkAllowChanges.Checked)
                                {
                                    xmlNode.InnerText = "false";
                                }
                                else
                                {
                                    xmlNode.InnerText = "true";
                                }

                                xmlNode = xmlDoc.SelectSingleNode("/my:myFields/my:GroupTasks", manager);
                                if (chkSingleTask2Group.Checked)
                                {
                                    xmlNode.InnerText = "true";
                                }
                                else
                                {
                                    xmlNode.InnerText = "false";
                                }

                                xmlNode = xmlDoc.SelectSingleNode("/my:myFields/my:CreateTasksInSerial", manager);
                                if (!chkWorkflowParalel.Checked)
                                {
                                    xmlNode.InnerText = "true";
                                }
                                else
                                {
                                    xmlNode.InnerText = "false";
                                }
                                XmlNode xmlNodeVoting = xmlDoc.SelectSingleNode("/my:myFields/my:Voting", manager);
                                XmlNode xmlNodeWantedTasks = xmlDoc.SelectSingleNode("/my:myFields/my:WantedTasks", manager);
                                if (chkCompleteWF.Checked)
                                {
                                    // HACK: Remove the nil=true attribute
                                    try
                                    {
                                        xmlNodeWantedTasks.Attributes.Remove(xmlNodeWantedTasks.Attributes["nil", "http://www.w3.org/2001/XMLSchema-instance"]);
                                    }
                                    catch (Exception)
                                    {
                                    }
                                    xmlNodeWantedTasks.InnerText = txtWantedTasks.Text;
                                    xmlNodeVoting.InnerText = "true";
                                }
                                else
                                {
                                    xmlNodeWantedTasks.InnerText = string.Empty;
                                    xmlNodeVoting.InnerText = "false";
                                }

                                association.AssociationData = xmlDoc.OuterXml;
                                list.UpdateWorkflowAssociation(association);
                            }
                        }
                    }
                }     
            }
        }

        foreach (TreeNode subNode in node.ChildNodes)
        {
            cnt += ApplyApprovalSettings(subNode);
        }
        return cnt;
    }
    #endregion
</script>